-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libsyntax_pos: Don't use packed attribute for Span on sparc64/v9 #45679
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nikomatsakis (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
src/libsyntax_pos/span_encoding.rs
Outdated
#[cfg(any(target_arch = "sparc64", | ||
target_arch = "sparcv9"))] | ||
#[derive(Clone, Copy, PartialEq, Eq, Hash)] | ||
pub struct Span(u32); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could simplify this whole thing into:
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(not(any(target_arch = "sparc64", target_arch = "sparcv9")), repr(packed))]
pub struct Span(u32);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I was expecting that there would be a simpler way. I'll try it out.
src/libsyntax_pos/span_encoding.rs
Outdated
@@ -25,10 +25,19 @@ use std::cell::RefCell; | |||
/// The primary goal of `Span` is to be as small as possible and fit into other structures | |||
/// (that's why it uses `packed` as well). Decoding speed is the second priority. | |||
/// See `SpanData` for the info on span fields in decoded representation. | |||
|
|||
/// Don't use packed attribute on sparc64/v9, see: #45509 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please prefix the comment with FIXME:
to make this line easier to be found.
Couldn't we just implement this safely on all architectures by implementing e.g.
(Maybe do the same for (@arielb1 and I had talked about just making |
Due the limitation that #[derive(...)] on #[repr(packed)] structs does not guarantee proper alignment of the compiler-generated impls is not guaranteed (rust-lang#39696), the change in rust-lang#44646 to compress Spans results in the compiler generating code with unaligned access. Until rust-lang#39696 has been fixed, the issue can be worked around by not using the packed attribute on sparc64 and sparcv9 on the Span struct. Fixes: rust-lang#45509
6ae8983
to
d4745f8
Compare
Yes, that would be possible, too. We have verified this with: extern crate core;
use core::cmp::PartialEq;
#[repr(packed)]
struct Demo(u8,u32);
impl PartialEq for Demo {
fn eq(&self, rhs: &Demo) -> bool {
// This crashes with bus error
// PartialEq::eq(&self.0, &rhs.0) && PartialEq::eq(&self.1, &rhs.1)
// This doesn't
self.0 == rhs.0 && self.1 == rhs.1
}
}
fn main() {
let a = Demo(0,4);
let b = Demo(0,4);
if a != b {
println!("Hello World!");
}
} But I guess that would just work around #39696 in a different way. |
@kennytm I have just verified that your variant works as well. Thanks for the heads-up! |
So which version should we do? My concern with the current one is that there may be other platforms where unaligned accesses are unsafe. Maybe we could invert the Otherwise, we could write the "correct everywhere" impls. I'm good with either one, I think. cc @arielb1, who may have an opinion |
From my current knowledge, this affects sparc* only from the platforms that are supported by Rust. In fact, from the 20+ architectures, unaligned access results in a "Bus Error" on sparc64 (and the old sparc) only. Other architectures tend to use kernel helpers if the alignment needs to be fixed which can slow down the overall access. |
Are there many other types using
that then implements |
Unless we want to specialize on the fields being |
@glaubitz well if @petrochenkov and @arielb1 agree, who am I to disagree. Care to port this to "the b012d0d solution"? |
If I understand correctly, this particular change would cause the build to fail but not yet fix the actual bug, correct? I'm also not sure whether my Rust skills are sufficient enough yet to help implement such a particular fix. |
@glaubitz I have to admit, clicking on that commit, I am not sure what was meant either. My assumption was that it is rewriting the partial-eq and other impls to copy the fields out, such as we discussed earlier (I'd probably favor a helper type, as I described here), but perhaps @petrochenkov or @arielb1 can elaborate. |
That's the idea, either in |
@glaubitz think you will have time to work on this? |
@nikomatsakis Do you mean just implementing the |
I just need to actually change my |
@nikomatsakis @arielb1 Sure. If there is anything to test on SPARC, let me know. |
We'll let you know when my PR lands. |
@arielb1 should this PR be closed? |
Sure. |
Due the limitation that #[derive(...)] on #[repr(packed)] structs does not guarantee proper alignment of the compiler-generated impls is not guaranteed (#39696), the change in #44646 to compress Spans results in the compiler generating code with unaligned access.
Until #39696 has been fixed, the issue can be worked around by not using the packed attribute on sparc64 and sparcv9 on the Span struct.
Fixes: #45509